home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb.new / gdb-3.98 / gdb / solib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-01  |  9.5 KB  |  348 lines

  1. /* Copyright (C) 1990 Free Software Foundation, Inc.
  2.  
  3. This file is part of GDB.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /*
  20. **    symbol definitions
  21. */
  22. #include <sys/types.h>
  23. #include <string.h>
  24. #include <link.h>
  25. #include <sys/param.h>
  26. #include <fcntl.h>
  27. #include <stdio.h>
  28. #include "defs.h"
  29. #include "param.h"
  30. #include "symtab.h"
  31. #include "gdbcore.h"
  32. #include "command.h"
  33. #include "target.h"
  34. #include "frame.h"
  35. #include "regex.h"
  36.  
  37. extern char *getenv();
  38.  
  39. /*
  40. **    local data declarations
  41. */
  42. #define MAX_PATH_SIZE 256
  43. struct so_list {
  44.     struct link_map inferior_lm;        /* inferior link map */
  45.     struct link_map *inferior_lm_add;
  46.     long   ld_text;
  47.     char inferior_so_name[MAX_PATH_SIZE];    /* Shared Object Library Name */
  48.     struct so_list *next;            /* Next Structure */
  49.     int    symbols_loaded;
  50.     bfd *so_bfd;
  51.     struct section_table *so_sections;
  52.     struct section_table *so_sections_end;
  53. };
  54.  
  55. static struct so_list *so_list_head = 0;
  56.  
  57. /*
  58. ** Build a section map for a shared library, record its text size in
  59. ** the so_list structure and set up the text section of the shared lib.
  60. */
  61. static void
  62. solib_map_sections(so)
  63. struct so_list *so;
  64. {
  65.   char *filename;
  66.   char *scratch_pathname;
  67.   int scratch_chan;
  68.   struct section_table *p;
  69.   
  70.   filename = tilde_expand (so->inferior_so_name);
  71.   make_cleanup (free, filename);
  72.   
  73.   scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
  74.                 &scratch_pathname);
  75.   if (scratch_chan < 0)
  76.     scratch_chan = openp (getenv ("LD_LIBRARY_PATH"), 1, filename, O_RDONLY, 0,
  77.                 &scratch_pathname);
  78.   if (scratch_chan < 0)
  79.     perror_with_name (filename);
  80.  
  81.   so->so_bfd = bfd_fdopenr (scratch_pathname, NULL, scratch_chan);
  82.   if (!so->so_bfd)
  83.     error ("Could not open `%s' as an executable file: %s",
  84.        scratch_pathname, bfd_errmsg (bfd_error));
  85.   if (!bfd_check_format (so->so_bfd, bfd_object))
  86.     error ("\"%s\": not in executable format: %s.",
  87.        scratch_pathname, bfd_errmsg (bfd_error));
  88.   if (build_section_table (so->so_bfd, &so->so_sections, &so->so_sections_end))
  89.     error ("Can't find the file sections in `%s': %s", 
  90.        exec_bfd->filename, bfd_errmsg (bfd_error));
  91.  
  92.   for (p = so->so_sections; p < so->so_sections_end; p++)
  93.     {
  94.       if (strcmp (bfd_section_name (so->so_bfd, p->sec_ptr), ".text") == 0)
  95.     {
  96.       /* Determine length of text section and relocate it. */
  97.       so->ld_text = p->endaddr - p->addr;
  98.       p->addr += (CORE_ADDR)so->inferior_lm.lm_addr;
  99.       p->endaddr += (CORE_ADDR)so->inferior_lm.lm_addr;
  100.     }
  101.       else
  102.     /* All other sections are ignored for now. */
  103.     p->addr = p->endaddr = 0;
  104.     }
  105. }
  106.  
  107. /*=======================================================================*/
  108.  
  109. /*    find_solib
  110. **
  111. **Description:
  112. **
  113. **    This module contains the routine which finds the names of any loaded
  114. **    "images" in the current process. The argument in must be NULL on the
  115. **    first call, and then the returned value must be passed in on
  116. **    subsequent calls. This provides the capability to "step" down the
  117. **    list of loaded objects. On the last object, a NULL value is returned.
  118. **    The arg and return value are "struct link_map" pointers, as defined
  119. **    in <link.h>.
  120. **
  121. **    NOTE: This only works under SunOS4.0.
  122. */
  123.  
  124. struct so_list *find_solib(so_list_ptr)
  125. struct so_list *so_list_ptr;            /* so_list_head position ptr */
  126. {
  127. struct so_list *so_list_next = 0;
  128. CORE_ADDR inferior_dynamic_ptr = 0;
  129. struct link_map *inferior_lm = 0;
  130. struct link_dynamic inferior_dynamic_cpy;
  131. struct link_dynamic_2 inferior_ld_2_cpy;
  132. struct so_list *new;
  133. int i;
  134.  
  135.      if (!so_list_ptr) {
  136.      if (!(so_list_next = so_list_head)) {
  137.          for (i = 0; i < misc_function_count; i++) {
  138.          if (!strcmp (misc_function_vector[i].name, "_DYNAMIC")) {
  139.              inferior_dynamic_ptr = misc_function_vector[i].address;
  140.              break;
  141.          }    
  142.          }        
  143.          if (inferior_dynamic_ptr) {
  144.          read_memory(inferior_dynamic_ptr, &inferior_dynamic_cpy, sizeof(struct link_dynamic));
  145.          if (inferior_dynamic_cpy.ld_version == 3) {
  146.              read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2,
  147.                  &inferior_ld_2_cpy,
  148.                  sizeof(struct link_dynamic_2));
  149.              inferior_lm = inferior_ld_2_cpy.ld_loaded;
  150.          }
  151.          }
  152.      }
  153.      } else {
  154.      /*
  155.      ** Advance to next local abbreviated load_map structure
  156.      */
  157.      if (!(inferior_lm = so_list_ptr->inferior_lm.lm_next)) {
  158.          /* See if any were added, but be quiet if we can't read
  159.         from the target any more.  */
  160.          int status;
  161.  
  162.          status = target_read_memory (
  163.             (CORE_ADDR)so_list_ptr->inferior_lm_add,
  164.             (char *)&so_list_ptr->inferior_lm,
  165.             sizeof(struct link_map));
  166.          if (status == 0)
  167.            inferior_lm = so_list_ptr->inferior_lm.lm_next;
  168.          else
  169.            inferior_lm = 0;
  170.      }
  171.      so_list_next = so_list_ptr->next;
  172.      }
  173.      if ((!so_list_next) && inferior_lm) {
  174.      /* 
  175.      ** Get Next LM Structure from inferior image and build
  176.      ** an local abbreviated load_map structure
  177.      */
  178.      new = (struct so_list *) xmalloc(sizeof(struct so_list));
  179.          new->inferior_lm_add = inferior_lm;
  180.      read_memory((CORE_ADDR)inferior_lm,
  181.              &new->inferior_lm,
  182.              sizeof(struct link_map));
  183.  
  184.      read_memory((CORE_ADDR)new->inferior_lm.lm_name,
  185.              new->inferior_so_name,
  186.              MAX_PATH_SIZE - 1);
  187.      new->inferior_so_name[MAX_PATH_SIZE - 1] = 0;
  188.      /* Zero everything after the first terminating null */
  189.      strncpy(new->inferior_so_name, new->inferior_so_name, MAX_PATH_SIZE);
  190.  
  191. #if 0
  192.      /* This doesn't work for core files, so instead get ld_text
  193.         using solib_map_sections (below).  */
  194.      read_memory((CORE_ADDR)new->inferior_lm.lm_ld,
  195.              &inferior_dynamic_cpy,
  196.              sizeof(struct link_dynamic));
  197.      read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2,
  198.              &inferior_ld_2_cpy,
  199.              sizeof(struct link_dynamic_2));
  200.      new->ld_text = inferior_ld_2_cpy.ld_text;
  201. #endif
  202.  
  203.      new->next = 0;
  204.      new->symbols_loaded = 0;
  205.      new->so_bfd = NULL;
  206.      new->so_sections = NULL;
  207.      if (so_list_ptr)
  208.          so_list_ptr->next = new;
  209.      else
  210.          so_list_head = new;
  211.  
  212.      solib_map_sections (new);
  213.  
  214.      so_list_next = new;
  215.      }
  216.      return(so_list_next);
  217. }
  218.  
  219. /*
  220. ** Called by core_xfer_memory if the transfer form the core file failed.
  221. ** We try to satisfy the request from the text sections of the shared libs.
  222. */
  223. int
  224. solib_xfer_memory (memaddr, myaddr, len, write)
  225.      CORE_ADDR memaddr;
  226.      char *myaddr;
  227.      int len;
  228.      int write;
  229. {
  230.   int res;
  231.   register struct so_list *so = 0;
  232.  
  233.   while (so = find_solib(so))
  234.     {
  235.       res = xfer_memory (memaddr, myaddr, len, write,
  236.                  so->so_bfd, so->so_sections, so->so_sections_end);
  237.       if (res)
  238.     return res;
  239.     }
  240.   return 0;
  241. }
  242. /*=======================================================================*/
  243.  
  244. void solib_add(arg_string, from_tty)
  245. char *arg_string;
  246. int from_tty;
  247. {    
  248.     register struct so_list *so = 0;       /* link map state variable */
  249.     char *val;
  250.  
  251.     if (arg_string == 0)
  252.     re_comp (".");
  253.     else if (val = (char *) re_comp (arg_string)) {
  254.     error ("Invalid regexp: %s", val);
  255.     }
  256.  
  257.     /* Getting new symbols may change our opinion about what is
  258.        frameless.  */
  259.     reinit_frame_cache ();
  260.  
  261.     printf_filtered ("All shared libraries");
  262.     if (arg_string)
  263.       printf_filtered (" matching regular expresion \"%s\"", arg_string);
  264.     printf_filtered (":\n");
  265.     
  266.     dont_repeat();
  267.  
  268.     while (so = find_solib(so)) {
  269.     if (re_exec(so->inferior_so_name)) {
  270.         if (so->symbols_loaded) {
  271.         printf("Symbols already loaded for %s\n", so->inferior_so_name);
  272.         } else {
  273.         symbol_file_add (so->inferior_so_name, from_tty,
  274.                  (unsigned int)so->inferior_lm.lm_addr, 0);
  275.         so->symbols_loaded = 1;
  276.         }
  277.     }
  278.     }
  279. }
  280. /*=======================================================================*/
  281.  
  282. static void solib_info()
  283. {
  284. register struct so_list *so = 0;      /* link map state variable */
  285.  
  286.     while (so = find_solib(so)) {
  287.     if (so == so_list_head) {
  288.         printf("      Address Range      Symbols     Shared Object Library\n");
  289.     }
  290.     printf(" 0x%08x - 0x%08x   %s   %s\n", 
  291.         so->inferior_lm.lm_addr, 
  292.         so->inferior_lm.lm_addr + so->ld_text - 1,
  293.         (so->symbols_loaded ? "Yes" : "No "),
  294.         so->inferior_so_name);
  295.     }
  296.     if (!so_list_head) {
  297.     printf("No shared libraries loaded at this time.\n");    
  298.     }
  299. }
  300.  
  301. /*
  302. ** Called by Insert Breakpoint to see if Address is Shared Library Address 
  303. */
  304. int
  305. solib_address(address)
  306.      CORE_ADDR address;
  307. {
  308. register struct so_list *so = 0;       /* link map state variable */
  309.  
  310.     while (so = find_solib(so)) {
  311.     if ((address >= (CORE_ADDR) so->inferior_lm.lm_addr) &&
  312.         (address < (CORE_ADDR) so->inferior_lm.lm_addr + so->ld_text))
  313.       return 1;
  314.     }
  315.     return 0;
  316. }
  317.  
  318. /*
  319. ** Called by free_all_symtabs
  320. */
  321. void 
  322. clear_solib()
  323. {
  324. struct so_list *next;
  325.  
  326.   while (so_list_head) {
  327.     if (so_list_head->so_sections)
  328.       free (so_list_head->so_sections);
  329.     if (so_list_head->so_bfd)
  330.       bfd_close (so_list_head->so_bfd);
  331.     next = so_list_head->next;
  332.     free(so_list_head);
  333.     so_list_head = next;
  334.   }
  335.     
  336. }
  337.  
  338. void
  339. _initialize_solib()
  340. {
  341.  
  342.   add_com("sharedlibrary", class_files, solib_add,
  343.        "Load shared object library symbols for files matching REGEXP.");
  344.   add_info("sharedlibrary", solib_info, 
  345.        "Status of loaded shared object libraries");
  346.  
  347. }
  348.